﻿/// <summary>
/// Create By The 19056821103@189.cn
/// </summary>
using _537_App_Store.Form;
using _537_App_Store.Models;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using System.Xml;
using System.Xml.Serialization;

namespace _537_App_Store
{
    public partial class MainWindow : Window
    {
        public static string? ConfigFilePath;    // 配置文件路径
        public static string? ServerAddress;     // 服务器地址
        public MainWindow()
        {
            MessageBox.Show(this.Title);
          
            InitializeComponent();
            ServerSettingAsync();
            RefreshButton_Click(this, null);
        }

        /// <summary>
        /// 创建服务器设置
        /// </summary>
        private static async void ServerSettingAsync()
        {
            var DefaultServerAddress = "https://537store.irabbitstudio.com.cn/";

            try
            {
                var configFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                configFolder = System.IO.Path.Combine(configFolder, "537AppStore");
                ConfigFilePath = System.IO.Path.Combine(configFolder, "Config.xml");

                if (!Directory.Exists(configFolder))
                {
                    Directory.CreateDirectory(configFolder);
                }

                if (!File.Exists(ConfigFilePath))
                {
                    var config = new Config
                    {
                        Server = new Server
                        {
                            Address = DefaultServerAddress
                        }
                    };
                    using var writer = XmlWriter.Create(ConfigFilePath);
                    var serializer = new XmlSerializer(typeof(Config));
                    serializer.Serialize(writer, config);

                    LoadServerConfig();// Load the server config
                }
                else
                {
                    LoadServerConfig();
                }
            }
            catch (Exception ex)
            {
                // 可以替换为日志记录或提示用户
                MessageBox.Show($"创建配置文件失败：{ex.Message}");
                // 或者使用日志框架记录异常
            }
        }
        private async void DownloadButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //首先获取点击的按钮，在获取listitem，然后获取数据
                var button = (Button)sender;
                var appItem = (ApplicationItem)button.DataContext;
                var Appname = appItem.Name;
                //通过Api获取数据。然后，做一个表，按照Appname查找，然后，将数据填充到详情窗口中。
                var client = new HttpClient();
                var response = await client.GetAsync(ServerAddress + "/api/Application");
                var json = await response.Content.ReadAsStringAsync();
                //json 反序列化为对象，忽略大小写
                JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

                var ApplicationListJson = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Application>>(json, options);
                //遍历列表，找到匹配的Appname
                foreach (var app in ApplicationListJson)
                {
                    if (app.Name == Appname)
                    {
                        /*
                         MessageBox.Show($"下载文件{app.Name}\n" +
                                         $"下载到{DownlaodFolder}文件夹\n" +
                                         $"链接是{downloadUrl}\n" +
                                         $"MD5:{app.MD5}");
                         MessageBox.Show(app.InstallCommand);
                         */
                        // 下载文件
                        //下载提示
                        //验证MD5，对比MD5
                        //下载完整提示
                        //运行命令

                        //下载，异步
                        try
                        {
                            await DownloadAndVerifyAsync(app);
                        }
                        catch (Exception)
                        {

                            throw;
                        }


                    }

                }


            }
            catch (Exception ex)
            {
                MessageBox.Show($"下载失败：{ex.Message}");
            }
        }
        static async Task DownloadAndVerifyAsync(_537AppStore_API.Model.Application app)
        {  //下载文件到下载文件夹
            var MainDownlaodFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            var DownloadFolder = System.IO.Path.Combine(MainDownlaodFolder, "Downloads");
            var downloadUrl = app.DownloadUrl;
            // 实现下载逻辑
            //下载文件到下载文件夹
            var fileName = System.IO.Path.GetFileName(app.RunFile);
            var filePath = System.IO.Path.Combine(DownloadFolder, fileName);
            if (string.IsNullOrEmpty(fileName))
            {
                throw new InvalidOperationException("无法从 RunFile 获取文件名。");
            }

            // 确保下载目录存在
            Directory.CreateDirectory(DownloadFolder);

            //MessageBox.Show($"开始下载: {fileName} ...");
            //下载地址
            MessageBox.Show($"下载地址: {downloadUrl}");
            using (var httpClient = new HttpClient())
            {
                // 1. 发送请求并获取响应
                HttpResponseMessage response = await httpClient.GetAsync(downloadUrl);
                response.EnsureSuccessStatusCode();
                // MessageBox.Show("开始获取文件流...");

                // 2. 检查状态码
                if (response.IsSuccessStatusCode)
                {
                    // MessageBox.Show("链接成功，开始下载文件流...");

                    // 3. 获取文件流
                    using (Stream fileStream = await response.Content.ReadAsStreamAsync())
                    {
                        // 4. 创建本地文件并复制流
                        using var localFileStream = File.Create(filePath);
                        await fileStream.CopyToAsync(localFileStream);
                    }
                    MessageBox.Show("下载完成。");
                }
                else
                {
                    MessageBox.Show($"下载失败，HTTP状态码: {response.StatusCode}");
                    return;
                }
            }

            // 5. 验证MD5
            //MessageBox.Show("开始验证MD5哈希值...");
            string calculatedMD5 = CalculateMD5(filePath);
            //  MessageBox.Show($"计算出的MD5: {calculatedMD5}");
            // MessageBox.Show($"期望的MD5: {app.MD5}");

            if (string.Equals(calculatedMD5, app.MD5, StringComparison.OrdinalIgnoreCase))
            {
                // MessageBox.Show("MD5验证成功!");

                // 6. 运行命令
                try
                {
                    MessageBox.Show($"正在尝试运行安装命令: {app.InstallCommand}");
                    // Process.Start 的推荐用法，传递文件路径
                    Process.Start(new ProcessStartInfo
                    {
                        FileName = filePath,
                        // 如果需要参数，可以设置 Arguments = "/S" (例如静默安装)
                        UseShellExecute = true // 对于直接执行文件很重要
                    });
                    MessageBox.Show("安装程序已启动。");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"启动安装程序时出错: {ex.Message}");
                }
            }
            else
            {
                MessageBox.Show("MD5验证失败! 下载的文件可能已损坏或被篡改。");
                // 可选：删除下载失败的文件
                try
                {
                    File.Delete(filePath);
                    MessageBox.Show("已删除验证失败的文件。");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"删除文件时出错: {ex.Message}");
                }
            }
        }
        static string CalculateMD5(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("要计算MD5的文件不存在。", filePath);
            }

            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(filePath))
                {
                    byte[] hashBytes = md5.ComputeHash(stream);
                    // 转换为小写十六进制字符串
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < hashBytes.Length; i++)
                    {
                        sb.Append(hashBytes[i].ToString("x2")); // "x2" 表示小写两位十六进制
                    }
                    return sb.ToString();
                }
            }
        }

        // 运行命令事件
        private async void ExecuteButton_Click(object sender, RoutedEventArgs e)
        {
            var button = (Button)sender;
            var commandName = (CommandListItem)button.DataContext;
            //通过Name来筛选，获取Command
            //通过Api获取数据。然后，做一个表，按照Appname查找，然后，将数据填充到详情窗口中。
            var client = new HttpClient();
            var response = await client.GetAsync(ServerAddress + "/api/Command");
            var json = await response.Content.ReadAsStringAsync();
            //json 反序列化为对象，忽略大小写
            JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };
            var commandList = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Command>>(json, options);
            foreach (var command in commandList)
            {
                if (command.CommandName == commandName.Name)
                {

                    //命令的一般形式有：cmd notepad
                    //命令的格式为：cmd /c notepad

                    //命令的格式为：powershell notepad
                    var CommandValue = command.CommandValue;
                    //运行命令
                    //先分段

                    try
                    {
                        // 1. 安全分割 shell 和命令内容
                        var parts = CommandValue.Split(new[] { ' ' }, 2, StringSplitOptions.None);
                        if (parts.Length < 2)
                        {
                            MessageBox.Show("命令格式不完整");
                            return;
                        }

                        var shell = parts[0].ToLower();
                        var command1 = parts[1];

                        // 2. 白名单验证：只允许 cmd 或 powershell
                        if (shell != "cmd" && shell != "powershell")
                        {
                            MessageBox.Show($"不支持的 shell: {shell}\n" +
                                $"仅支持CMD和PowerShell");
                            return;
                        }

                        // 3. 根据 shell 构建 ProcessStartInfo
                        var startInfo = new ProcessStartInfo
                        {
                            UseShellExecute = false,    // 使用命令行执行，不使用系统默认程序打开
                            CreateNoWindow = true,      // 不显示窗口
                            RedirectStandardOutput = true,// 重定向标准输出
                            RedirectStandardError = true// 重定向错误输出
                        };

                        if (shell == "cmd")
                        {
                            startInfo.FileName = "cmd.exe";
                            startInfo.Arguments = $"/c {command1}";
                        }
                        else if (shell == "powershell")
                        {
                            startInfo.FileName = "powershell.exe";
                            startInfo.Arguments = command1;
                        }

                        // 4. 启动进程并捕获输出
                        using (var process = new Process())
                        {
                            process.StartInfo = startInfo;
                            process.Start();

                            string output = process.StandardOutput.ReadToEnd();
                            string error = process.StandardError.ReadToEnd();
                            process.WaitForExit();

                            if (!string.IsNullOrEmpty(error))
                            {
                                MessageBox.Show($"Error: {error}");
                            }
                            else
                            {
                                MessageBox.Show($"Output: {output}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"执行失败: {ex.Message}");
                    }
                }
            }

        }


        private async void VisitButton_Click(object sender, RoutedEventArgs e)
        {
            var button = (Button)sender;
            var websiteName = (WebSiteItem)button.DataContext;
            var client = new HttpClient();
            var response = await client.GetAsync(ServerAddress + "/api/WebSite");
            var json = await response.Content.ReadAsStringAsync();
            //json 反序列化为对象，忽略大小写
            JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

            var WebSiteListJson = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Website>>(json, options);
            //遍历列表，找到匹配的Appname
            foreach (var website in WebSiteListJson)
            {
                if (website.Name == websiteName.Name)
                {
                    // 访问网站
                    //用默认浏览器打开网站链接

                    Process.Start(new ProcessStartInfo(website.Url) { UseShellExecute = true });
                }
            }
            //    // 实现访问网站逻辑
            //    Process.Start(new ProcessStartInfo(websiteItem.Url) { UseShellExecute = true });
        }
        //详情按钮点击事件
        private async void DetailsButton_Click(object sender, RoutedEventArgs e)
        {
            //判断点击的是哪个选项卡的按钮
            var selecectedTab = MainWindowTabControl.SelectedIndex;
            switch (selecectedTab)
            {
                //应用选项卡
                case 0:

                    //首先获取点击的按钮，在获取listitem，然后获取数据
                    var button = (Button)sender;
                    var appItem = (ApplicationItem)button.DataContext;
                    var Appname = appItem.Name;
                    //通过Api获取数据。然后，做一个表，按照Appname查找，然后，将数据填充到详情窗口中。
                    var client = new HttpClient();
                    var response = await client.GetAsync(ServerAddress + "/api/Application");
                    var json = await response.Content.ReadAsStringAsync();
                    //json 反序列化为对象，忽略大小写
                    JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

                    var ApplicationListJson = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Application>>(json, options);
                    //遍历列表，找到匹配的Appname
                    foreach (var app in ApplicationListJson)
                    {
                        if (app.Name == Appname)
                        {
                            _537AppStore_API.Model.Application Item = new _537AppStore_API.Model.Application()
                            {
                                Author = app.Author,
                                Name = app.Name,
                                Icon = app.Icon,
                                DownloadUrl = app.DownloadUrl,
                                Category = app.Category,
                                Description = app.Description,
                                id = app.id,
                                InstallCommand = app.InstallCommand,
                                InstallerType = app.InstallerType,
                                LastUpdated = app.LastUpdated,
                                License = app.License,
                                MD5 = app.MD5,
                                RunFile = app.RunFile,
                                Version = app.Version
                            };

                            //创建详情窗口
                            Application_Detailswindow window = new Application_Detailswindow(Item);
                            window.ShowDialog();
                        }
                    }
                    break;
                //命令选项卡
                case 1:
                    //首先获取点击的按钮，在获取listitem，然后获取数据
                    var button1 = (Button)sender;
                    var appItem1 = (CommandListItem)button1.DataContext;
                    var Appname1 = appItem1.Name;
                    //通过Api获取数据。然后，做一个表，按照Appname查找，然后，将数据填充到详情窗口中。
                    var client1 = new HttpClient();
                    var response1 = await client1.GetAsync(ServerAddress + "/api/Command");
                    var json1 = await response1.Content.ReadAsStringAsync();
                    //json 反序列化为对象，忽略大小写
                    JsonSerializerOptions options1 = new() { PropertyNameCaseInsensitive = true };
                    var commandList = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Command>>(json1, options1);
                    foreach (var command in commandList)
                    {
                        if (command.CommandName == Appname1)
                        {   //详情窗口
                            MessageBox.Show($"ID：{command.id}\n" +
                                            $"命令名称：{command.CommandName}\n" +
                                            $"命令值：{command.CommandValue}\n" +
                                            $"作者：{command.Author}\n" +
                                            $"上传时间：{command.CreateTime.ToString("yyyy-MM-dd dddd HH:mm:ss")}\n" +
                                            $"命令详情：{command.CommandDescription}");
                        }
                    }

                    break;
                //书签选项卡
                case 2:
                    var button2 = (Button)sender;
                    var appItem2 = (WebSiteItem)button2.DataContext;
                    var WebSiteName = appItem2.Name;

                    var client2 = new HttpClient();
                    var response2 = await client2.GetAsync(ServerAddress + "/api/WebSite");
                    var json2 = await response2.Content.ReadAsStringAsync();
                    //json 反序列化为对象，忽略大小写
                    JsonSerializerOptions options2 = new()
                    {
                        PropertyNameCaseInsensitive = true
                    };

                    var WebSiteListJson = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Website>>(json2, options2);
                    //遍历列表，找到匹配的Appname
                    foreach (var website in WebSiteListJson)
                    {
                        if (website.Name == WebSiteName)
                        {
                            var websiteDetailWindow = new Form.WebSite_Detailswindow(website);
                            websiteDetailWindow.ShowDialog();
                        }
                    }
                    break;
            }
        }


        private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            // MessageBox.Show(ServerAddress);
            ApplicationLoadToList();
            CommandLoadToList();
            WebSiteLoadToList();
        }

        private async void WebSiteLoadToList()
        {
            //https://537store.irabbitstudio.com.cn/api/WebSite
            try
            {
                // 从服务器获取应用列表
                var client = new HttpClient();
                var response = await client.GetAsync(ServerAddress + "/api/WebSite");
                var json = await response.Content.ReadAsStringAsync();
                //json 反序列化为对象，忽略大小写
                JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

                var Webs = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Website>>(json, options);
                if (Webs != null)
                {
                    WebsiteList.Items.Clear();
                    foreach (var item in Webs)
                    {
                        WebsiteList.Items.Add(new WebSiteItem
                        {
                            Name = item.Name,
                            Icon = item.Icon
                        });
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("获取网站列表失败：" + ex.Message);
            }
        }


        private void UploadProject_Click(object sender, RoutedEventArgs e)
        {
            Form.UploadWindow window = new Form.UploadWindow();
            window.ShowDialog();
        }
        /// <summary>
        /// 加载服务器配置
        /// </summary>
        private static void LoadServerConfig()
        {

            XmlSerializer serializer = new XmlSerializer(typeof(Config));
            //判断Config文件是否存在
            if (!File.Exists(ConfigFilePath))
            {
                MessageBox.Show("未找到配置文件，请先设置服务器地址");
                ServerSettingAsync();
                return;
            }
            using FileStream fileStream = new(ConfigFilePath, FileMode.Open);
            //
            Config config = (Config)serializer.Deserialize(fileStream);
            if (config == null)
            {
                MessageBox.Show("配置文件格式错误");
                return;
            }
            ServerAddress = config.Server.Address;
        }

        private void SettingNewServerAddressButton_Click(object sender, RoutedEventArgs e)
        {
            //弹出窗口输入服务器地址
            var NewServerAddress = Microsoft.VisualBasic.Interaction.InputBox("请输入新的服务器地址", "服务器地址", ServerAddress);
            if (NewServerAddress == null)
            {
                MessageBox.Show("取消设置");
                return;
            }
            if (NewServerAddress == "")
            {
                MessageBox.Show("请输入服务器地址");
                return;
            }
            ServerAddress = NewServerAddress;
            //var NewServerAddress = Microsoft.VisualBasic.Interaction.InputBox("请输入新的服务器地址", "服务器地址", ServerAddress);
            //如果点击取消，则返回null
            if (NewServerAddress != null)
            {
                ServerAddress = NewServerAddress;
                //写入到配置文件
                using FileStream fileStream = new(ConfigFilePath, FileMode.Create);
                XmlSerializer serializer = new(typeof(Config));

                Config config = new()
                {
                    Server = new Server
                    {
                        Address = ServerAddress
                    }
                };

                serializer.Serialize(fileStream, config);
                MessageBox.Show("服务器地址已保存");

            }
        }
        public async void ApplicationLoadToList()
        {
            try
            {
                // 从服务器获取应用列表
                var client = new HttpClient();
                var response = await client.GetAsync(ServerAddress + "/api/Application");
                var json = await response.Content.ReadAsStringAsync();
                //json 反序列化为对象，忽略大小写
                JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

                var ApplicationListJson = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Application>>(json, options);
                if (ApplicationListJson != null)
                {
                    ApplicationList.Items.Clear();
                    foreach (var item in ApplicationListJson)
                    {
                        ApplicationList.Items.Add(new ApplicationItem
                        {
                            Icon = item.Icon,
                            Name = item.Name,
                            Version = item.Version
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取应用列表失败：" + ex.Message);
            }


        }
        public async void CommandLoadToList()
        {
            try
            {
                // 从服务器获取应用列表
                var client = new HttpClient();
                var response = await client.GetAsync(ServerAddress + "/api/Command");
                var json = await response.Content.ReadAsStringAsync();
                //json 反序列化为对象，忽略大小写
                JsonSerializerOptions options = new() { PropertyNameCaseInsensitive = true };

                var commands = JsonSerializer.Deserialize<List<_537AppStore_API.Model.Command>>(json, options);
                if (commands != null)
                {
                    CommandList.Items.Clear();
                    foreach (var item in commands)
                    {
                        CommandList.Items.Add(new CommandListItem
                        {
                            Name = item.CommandName
                        });
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("获取命令列表失败：" + ex.Message);
            }
        }







        public class ApplicationItem
        {
            public string Name { get; set; }
            public string Icon { get; set; }
            public string Version { get; set; }
        }
        public class CommandListItem
        {
            public string Name { get; set; }

        }
        public class WebSiteItem
        {
            public string Name { get; set; }
            public string Icon { get; set; }
        }

        private void AboutButton_Click(object sender, RoutedEventArgs e)
        {
            var appname = Assembly.GetExecutingAssembly().GetName().Name;
            var version = Assembly.GetExecutingAssembly().GetName().Version;
            string[] Authors =
                {
                "537 Studio",
                "由Rabbit工作室提供服务器支持"
                };
            MessageBox.Show($"{appname} \n" +
                            $"V{version}\n" +
                            $"作者名单如下：\n{string.Join("\n", Authors)}",
                            "关于", MessageBoxButton.OK,
                                    MessageBoxImage.Information);
        }
    }
}